<?php
class ome_mdl_delivery extends dbeav_model{
    var $has_many = array(
        'delivery_items' => 'delivery_items',
        'delivery_order' => 'delivery_order',
        //'dly_items_pos'  => 'dly_items_pos', TODO:和zhangxu确认，是否需要
    );

    var $defaultOrder = array('order_createtime',' DESC');

    public function _filter($filter,$tableAlias=null,$baseWhere=null){
        if(isset($filter['extend_delivery_id'])){
            $where .= ' OR delivery_id IN ('.implode(',', $filter['extend_delivery_id']).')';
            unset($filter['extend_delivery_id']);
        }
        if (isset($filter['member_uname'])){
            $memberObj = &$this->app->model("members");
            $rows = $memberObj->getList('member_id',array('uname|has'=>$filter['member_uname']));
            $memberId[] = 0;
            foreach($rows as $row){
                $memberId[] = $row['member_id'];
            }
            $where .= '  AND member_id IN ('.implode(',', $memberId).')';
            unset($filter['member_uname']);
        }
        if (isset($filter['order_bn'])){
            $orderObj = &$this->app->model("orders");
            $rows = $orderObj->getList('order_id',array('order_bn|has'=>$filter['order_bn']));
            $orderId[] = 0;
            foreach($rows as $row){
                $orderId[] = $row['order_id'];
            }

            $deliOrderObj = &$this->app->model("delivery_order");
            $rows = $deliOrderObj->getList('delivery_id',array('order_id'=>$orderId));
            $deliveryId[] = 0;
            foreach($rows as $row){
                $deliveryId[] = $row['delivery_id'];
            }

            $where .= '  AND delivery_id IN ('.implode(',', $deliveryId).')';
            unset($filter['order_bn']);
        }
        if(isset($filter['product_bn'])){
            $itemsObj = &$this->app->model("delivery_items");
            $rows = $itemsObj->getDeliveryIdByPbn($filter['product_bn']);
            $deliveryId[] = 0;
            foreach($rows as $row){
                $deliveryId[] = $row['delivery_id'];
            }
            $where .= '  AND delivery_id IN ('.implode(',', $deliveryId).')';
            unset($filter['product_bn']);
        }
        if(isset($filter['product_barcode'])){
            $itemsObj = &$this->app->model("delivery_items");
            $rows = $itemsObj->getDeliveryIdByPbarcode($filter['product_barcode']);
            $deliveryId[] = 0;
            foreach($rows as $row){
                $deliveryId[] = $row['delivery_id'];
            }
            $where .= '  AND delivery_id IN ('.implode(',', $deliveryId).')';
            unset($filter['product_barcode']);
        }
        if(isset($filter['logi_no_ext'])){
            $logObj = &$this->app->model("delivery_log");
            $rows = $logObj->getDeliveryIdByLogiNO($filter['logi_no_ext']);
            $deliveryId[] = 0;
            foreach($rows as $row){
                $deliveryId[] = $row['delivery_id'];
            }
            $where .= '  AND delivery_id IN ('.implode(',', $deliveryId).')';
            unset($filter['logi_no_ext']);
        }
     	if(isset($filter['addonSQL'])){
            $where .= ' AND '.$filter['addonSQL'];
            unset($filter['addonSQL']);
        }
	    if(isset($filter['delivery_ident'])){
            $arr_delivery_ident = explode('_',$filter['delivery_ident']);
            $mdl_queue = app::get('ome')->model("print_queue");
            if(count($arr_delivery_ident) == 2){
                $ident_dly = array_pop($arr_delivery_ident);
                $ident = implode('-',$arr_delivery_ident);
                $queueItem = $mdl_queue->findQueueItem($ident,$ident_dly);
                if($queueItem){
                    $where .= '  AND delivery_id ='.$queueItem['delivery_id'].'';
                }else{
                    $where .= '  AND delivery_id IN (0)';
                }
            }else{
                $queue = $mdl_queue->findQueue($filter['delivery_ident'],'dly_bns');
                if($queue){
                    $where .= '  AND delivery_id IN ('.$queue['dly_bns'].')';
                }else{
                    $where .= '  AND delivery_id IN (0)';
                }
            }

            unset($filter['delivery_ident']);
        }
        if(isset($filter['ship_tel_mobile'])){
            $where .= ' AND (ship_tel=\''.$filter['ship_tel_mobile'].'\' or ship_mobile=\''.$filter['ship_tel_mobile'].'\')';
            unset($filter['ship_tel_mobile']);
        }
		if($filter['todo']==1){
            $where .= " AND (stock_status='false' or expre_status='false' or deliv_status='false')";
            unset($filter['todo']);
        }
        if($filter['todo']==2){
            $where .= " AND (stock_status='false' or expre_status='false')";
            unset($filter['todo']);
        }
        if($filter['todo']==3){
            $where .= " AND (expre_status='false' or deliv_status='false')";
            unset($filter['todo']);
        }
        if($filter['todo']==4){
            $where .= " AND expre_status='false'";
            unset($filter['todo']);
        }

        return parent::_filter($filter,$tableAlias,$baseWhere).$where;
    }

    public function getParentIdBybn($delivery_bn){
        $sql = 'SELECT parent_id from sdb_ome_delivery WHERE parent_id>0 and delivery_bn like \'%'.$delivery_bn.'%\' GROUP BY parent_id';
        $rows = $this->db->select($sql);
        return $rows;
    }


    /**
     * 取得物流公司名称
     */
    function getLogi_name(){
        $sql = " SELECT logi_id,logi_name FROM sdb_ome_delivery GROUP BY logi_id ";
        $row = $this->db->select($sql);
        return $row;
    }
    /**
     * 判断是否已有此物流单号，检验前物流单号可以任意修改
     *
     * @param string $logi_no
     * @param int $dly_id
     * @return boolean
     */
    function existExpressNo($logi_no, $dly_id=0,$order_id=0){
        //更新，conut走架构
        $filter['logi_no'] = $logi_no;
        $filter['delivery_id|noequal'] = $dly_id;//不等于，见dbeav：filter
        $filter['verify'] = 'true';

        if($order_id){
        	$filter['order_id'] = order_id;
        }
        
        //如果相同单号有
         $row = $this->db->selectRow('select count(*) as _count from sdb_ome_delivery d
         		join `sdb_ome_delivery_order` do on d.delivery_id=do.delivery_id 
         		where logi_no="'.$logi_no.'" and d.delivery_id!='.$dly_id.' and do.order_id!='.order_id);
	       
        $count = $row['_count'];
        if ($count > 0) {
        	return true;
        }else{
	        $row = $this->db->selectRow('select delivery_id from sdb_ome_delivery where logi_no="'.$logi_no.'" and delivery_id!='.$dly_id);
	        if($row){
	        	$this->db->exec('update sdb_ome_delivery set logi_no=null where delivery_id = '.$row['delivery_id']);
	        }
        	return false;
        }
       
    }

    /**
     * 判断发货单是否已合并过，
     *
     * @param array() $dly_ids
     * @return boolean
     */
    function existIsMerge($dly_ids){
        $ids = implode(',', $dly_ids);
        //更新，conut走架构
        $filter['delivery_id|in'] = $ids;
        $filter['parent_id|noequal'] = 0;

        $count = $this->count($filter);
        if ($count > 0) return true;
        return false;
    }

    /**
     * 判断发货单是否为合并后的发货单
     *
     * @param array() $dly_ids
     * @return boolean
     */
    function existIsMerge_parent($dly_id){
        $sql = "SELECT is_bind FROM sdb_ome_delivery where delivery_id = {$dly_id}";
        $row = $this->db->select($sql);
        if($row[0]['is_bind'] == 'true'){
            return true;
        }else{
            return false;
        }
    }


    /**
     * 更新发货单详情
     *
     * @param array() $dly
     * @param array() $delivery_id
     * @return boolean
     */
    function updateDelivery($dly, $delivery_id){

        $result = $this->update($dly, $delivery_id);
        if ($result){
            //更新发货物流信息
            foreach(kernel::servicelist('service.delivery') as $object=>$instance){
                if(method_exists($instance,'update_logistics_info')){
                    $instance->update_logistics_info($delivery_id['delivery_id']);
                }
            }
        }
        return $result;
    }

    /**
     * 记录商品当天仓库的发货数量
     *
     * @param int $branch_id
     * @param int $number
     * @param int $product_id
     *
     * @return boolean
     */
    function createStockChangeLog($branch_id,$number,$product_id){
        $branchObj = &$this->app->model('branch');
        $stock_clObj = &$this->app->model('stock_change_log');
        $productObj = &$this->app->model('products');
        $branch = $branchObj->dump($branch_id);
        $day = $branch['stock_safe_day'];
        $time = $branch['stock_safe_time'];

        $log_bn = date('Ymd');
        $now = time();
        $todaylog = $stock_clObj->dump(array('log_bn'=>$log_bn,'product_id'=>$product_id,'branch_id'=>$branch_id));
        if ($todaylog){
            $log['log_id'] = $todaylog['log_id'];
            $log['store'] = $todaylog['store']+$number;

            $stock_clObj->save($log);
        }else {
            $log['product_id'] = $product_id;
            $log['branch_id'] = $branch_id;
            $log['log_bn'] = $log_bn;
            $log['create_time'] = time();
            $log['store'] = $number;

            $pro_info = $productObj->dump($product_id);
            $log['bn'] = $pro_info['bn'];
            $log['product_name'] = $pro_info['name'].($pro_info['spec_desc']?"(".$pro_info['spec_desc'].")":"");

            $stock_clObj->save($log);
        }
        return true;
    }

    /**
     * 判断发货单对应的订单处理状态是否为取消或异常
     *
     * @param bigint $dly_id
     * @param string $is_bind
     *
     * @return boolean
     */
    function existOrderStatus($dly_id, $is_bind){
        if ($is_bind == 'true'){
            $ids = $this->getItemsByParentId($dly_id);
        }else {
            $ids = $dly_id;
        }
        //$sql = "SELECT COUNT(*) AS '_count'  FROM sdb_ome_delivery_order dord JOIN sdb_ome_orders o ON dord.order_id=o.order_id WHERE dord.delivery_id in ($ids) AND (o.process_status='cancel' OR o.abnormal='true' OR o.disabled='true') ";
        $sql = "SELECT COUNT(*) AS '_count'  FROM sdb_ome_delivery WHERE delivery_id in ($ids) AND (status='cancel' OR status='back' OR status='timeout' OR status='failed' OR disabled='true' OR pause='true') ";
        $row = $this->db->select($sql);
        if ($row[0]['_count'] > 0){
            return false;
        }else {
            return true;
        }
    }

    function existOrderPause($dly_id, $is_bind){
        if ($is_bind == 'true'){
            $ids = $this->getItemsByParentId($dly_id);
        }else {
            $ids = $dly_id;
        }
        $sql = "SELECT COUNT(*) AS '_count'  FROM sdb_ome_delivery_order dord JOIN sdb_ome_orders o ON dord.order_id=o.order_id WHERE dord.delivery_id in ($ids) AND (o.process_status='cancel' OR o.abnormal='true' OR o.disabled='true' OR o.pause='true') ";
        $row = $this->db->select($sql);
        if ($row[0]['_count'] > 0){
            return false;
        }else {
            return true;
        }
    }

    /**
     * 获取与本发货单配送信息(bind_key)相同的发货单列表(父id为0)
     *
     * @param bigint $dly_id
     *
     * @return array()
     */
    function getSameKeyList($dly_id){
        $dly = $this->dump($dly_id,'bind_key');
        $filter['bind_key'] = $dly['bind_key'];
        $filter['process']  = 'false';
        $filter['status']   = array('ready','progress');
        $filter['type']     = 'normal';
        $filter['parent_id'] = '0';
        $data = $this->getList('*', $filter, 0, -1);
        foreach ($data as $key => $item){
            if ($this->existOrderStatus($item['delivery_id'], $item['is_bind']) && $this->existOrderPause($item['delivery_id'], $item['is_bind'])){
                $data[$key]['order_status'] = 'OK';
            }else{
                $data[$key]['order_status'] = 'ERROR';
            }
            if ($item['is_bind'] == 'true'){
                $data[$key]['ids'] = $this->getItemsByParentId($item['delivery_id'],'array','*');
            }
        }
        return $data;
    }

    /**
     * 利用父ID获取子发货单的ID
     *
     * @param bigint $parent_id
     *
     * @return string/array         id字符串或id数组或者id对应所有数据
     */
    function getItemsByParentId($parent_id, $return='string', $column='delivery_id'){
        $filter['parent_id'] = $parent_id;
        $rows = $this->getList($column, $filter, 0, -1);
        if (empty($rows)){
            $ids = '0';
            return $ids;
        }
        foreach ($rows as $item){
            $data[] = $item['delivery_id'];
        }
        if ($return == 'string'){
            $ids = implode(',', $data);
        }elseif ($column == 'delivery_id'){
            $ids = $data;
        }else {
            foreach ($rows as $key => $item){
                if ($this->existOrderStatus($item['delivery_id'], $item['is_bind'])  && $this->existOrderPause($item['delivery_id'], $item['is_bind'])){
                    $rows[$key]['order_status'] = 'OK';
                }else {
                    $rows[$key]['order_status'] = 'ERROR';
                }
            }
            $ids = $rows;
        }
        return $ids;
    }

    /**
     * 拆分发货单
     * 作用：先将大的发货单拆分掉，再将不需要拆分的子发货单合并
     *
     * @param bigint $parent_id
     * @param array  $items            需要拆分的items
     *
     * @return boolean
     */
    function splitDelivery($parent_id, $items=''){
        $filter['parent_id'] = $parent_id;
        $filter2['delivery_id'] = $parent_id;
        $dly = $this->dump($filter2);
        $ids = $this->getItemsByParentId($parent_id, 'array');
        if ($this->resumeDelivery($filter)){//重置发货单
            $this->delete($filter2);//删除delvery表
            $this->deleteDeliveryOrderByDeliveryId($filter2);//删除delivery_order表
            //$this->deleteDeliveryItemsPosByDeliveryId($filter2);//删除dly_items_pos表
            $this->deleteDeliveryItemsByDeliveryId($filter2);//删除delivery_items表
            $this->deleteDeliveryItemDetailByDeliveryId($filter2);//删除delivery_items_detail表

            $opObj = &$this->app->model('operation_log');
            if (empty($items)){
                $opObj->write_log('delivery_split@ome', $parent_id, '拆分发货单('.$parent_id.')');
            }else {
                foreach ($items as $i){
                    $delivery = $this->dump($i, 'delivery_bn');
                    $arr_idd[] = $delivery['delivery_bn'];
                }
                $idd = implode(',',$arr_idd);
                $opObj->write_log('delivery_split@ome', $parent_id, '拆分发货单('.$idd.')');
            }

            if (is_array($items)) {
                $id = array_diff($ids, $items);//获取不需要拆分的子发货单ID
                sort($id);
                $this->mergeDelivery($id, $dly);//重新合并不需要拆分的子发货单
            }
            return true;
        }else {
            return false;
        }
    }
    /**
     * 合并发货单处理
     *
     * @param array() $dly_ids
     * @param array() $delivery => array(
                                        'logi_id' => '',
                                        'logi_name' => '',

                                        'delivery_bn' => '',
                                        'logi_no' => '',
                                        'status' => '',
                                        'stock_status' => '',
                                        'deliv_status' => '',
                                        'expre_status' => '',
     *                             );
     * $delivery的键值可以只传前两个或者都传
     *
     * @return boolean
     */
    function merge($dly_ids, $delivery=array()){
        if (!is_array($dly_ids)) return false;
        if (count($dly_ids) < 2) return false;
        if ($delivery){
            if (!$delivery['logi_id']) return false;
            $tmp = $delivery;
            unset($delivery['logi_id']);
            unset($delivery['logi_name']);
            if ($delivery){
                if (!$delivery['delivery_bn']) return false;
                return $this->mergeDelivery($dly_ids, $tmp);
            }else {
                $dly['logi_id'] = $tmp['logi_id'];
                $dly['logi_name'] = $tmp['logi_name'];
                $dly['logi_no'] = null;
                $dly['delivery_bn'] = $this->gen_id();
                $dly['status']          = 'ready';
                $dly['stock_status']    = 'false';
                $dly['deliv_status']    = 'false';
                $dly['expre_status']    = 'false';
                return $this->mergeDelivery($dly_ids, $dly);
            }
        }else {
            $tmp = $dly_ids;
            $id = array_shift($tmp);
            unset($tmp);
            $delivery = $this->dump($id, 'logi_id,logi_name');

            $dly['logi_id'] = $delivery['logi_id'];
            $dly['logi_name'] = $delivery['logi_name'];
            $dly['logi_no'] = null;
            $dly['delivery_bn'] = $this->gen_id();
            $dly['status']          = 'ready';
            $dly['stock_status']    = 'false';
            $dly['deliv_status']    = 'false';
            $dly['expre_status']    = 'false';

            return $this->mergeDelivery($dly_ids, $dly);
        }
    }
    /**
     * 合并发货单
     *
     * @param array() $dly_ids
     *
     * @return boolean
     */
    function mergeDelivery($dly_ids, $delivery){
        if ($dly_ids && is_array($dly_ids)){
            foreach ($dly_ids as $key => $_id){
                $_dly = $this->db->selectrow("SELECT delivery_id,delivery_bn,parent_id FROM sdb_ome_delivery WHERE delivery_id=".$_id);
                if ($_dly['parent_id'] != 0){
                    trigger_error("发货单:".$_dly['delivery_bn']."已合并过", E_USER_ERROR);
                    return false;
                    //unset($dly_ids[$key]);
                }
            }
        }
        if (count($dly_ids) < 2) return false;

        $dly_corpObj = app::get('ome')->model('dly_corp');
        $opObj = &$this->app->model('operation_log');
        if (!is_array($dly_ids)) return false;
        $new_ids = array();//单个小发货单ID数组
        $net_weight = 0;
        $weight = 0;
        foreach ($dly_ids as $item){
            $dly = $this->dump($item);
            $net_weight += $dly['net_weight'];
            $weight += $dly['weight'];
            if ($dly['is_bind'] == 'true'){
                $ids = $this->getItemsByParentId($item, 'array');
                if (is_array($ids)){
                    $parents[] = $item;//大发货单ID数组
                    $new_ids = array_merge($new_ids, $ids);
                }
            }else {
                $new_ids[] = $item;
            }
        }
        if (count($new_ids) < 2) return false;

        unset($dly['delivery_id']);
        unset($dly['verify']);
        unset($dly['cost_protect']);
        //组织合并后的大发货单的预计物流费用
        $corp  = $dly_corpObj->dump($delivery['logi_id']);//物流公司信息
        //物流费用计算
        $area = $dly['consignee']['area'];
        $arrArea = explode(':', $area);
        $area_id = $arrArea[2];
        if (isset($corp['area_fee_conf']) && $corp['area_fee_conf']){
            $area_fee_conf = unserialize($corp['area_fee_conf']);
            foreach($area_fee_conf as $k=>$v){
                 $areas = explode(',',$v['areaGroupId']);

                 // 再次解析字符
                  foreach ($areas as &$strArea){
                    if (strpos($strArea, '|') !== false){
                       $strArea = substr($strArea, 0, strpos($strArea, '|'));
                        // 取当前area id对应的最上级的区域id
                        $objRegions = app::get('ectools')->model('regions');
                        $arrRegion = $objRegions->dump($area_id);
                        while ($row = $objRegions->getRegionByParentId($arrRegion['p_region_id'])){
                             $arrRegion = $row;
                             $tmp_area_id = $row['region_id'];
                             if ($tmp_area_id == $strArea){
                                $area_id = $tmp_area_id;
                                        break;
                                    }
                                }
                            }
                        }

                        if(in_array($area_id,$areas))
                        {
                            //如果地区在其中，优先使用地区设置的配送费用，及公式
                            $corp['firstprice'] = $v['firstprice'];
                            $corp['continueprice'] = $v['continueprice'];
                            $corp['dt_expressions'] = $v['dt_expressions'];
                            break;
                        }
                    }
         }


        $price = utils::cal_fee($corp['dt_expressions'], $net_weight, 0,$corp['firstprice'],$corp['continueprice']); //TODO 生成快递费用
        if($delivery['logi_id']){
            $dly_corp = $dly_corpObj->dump($delivery['logi_id']);
            $logi_name = $dly_corp['name'];
            //计算保价费用
            $protect = $dly_corp['protect'];
            if($protect == 'true'){
                $is_protect = 'true';
                $protect_rate = $dly_corp['protect_rate'];//保价费率
                $protect_price = $protect_rate * $net_weight;
                $minprice = $dly_corp['minprice'];//最低报价费用
                if($protect_price < $minprice){
                    $cost_protect = $minprice;
                }else{
                    $cost_protect = $protect_price;
                }
            }
        }
        $dly['cost_protect'] = $cost_protect;
        $dly['is_protect'] = $is_protect ? $is_protect : 'false';
        $new_dly = $dly;//新的大发货单sdf结构
        $new_dly['memo']            = null;
        $new_dly['delivery_bn']     = $delivery['delivery_bn'];
        $new_dly['net_weight']      = $net_weight;
        $new_dly['weight']          = $weight;
        $new_dly['is_bind']         = 'true';
        $new_dly['logi_no']         = $delivery['logi_no'];
        $new_dly['logi_id']         = $delivery['logi_id'];
        $new_dly['logi_name']       = $delivery['logi_name'];
        $new_dly['parent_id']       = 0;
        $new_dly['status']          = $delivery['status'];
        $new_dly['stock_status']    = $delivery['stock_status'];
        $new_dly['deliv_status']    = $delivery['deliv_status'];
        $new_dly['expre_status']    = $delivery['expre_status'];
        $new_dly['delivery_cost_expect'] = $price;

    //获取大发货单的订单创建时间 取各个发货单最小的订单创建时间
    $order_createtime = $this->getDeliveryOrderCreateTime($dly_ids);
    if($order_createtime){
        $new_dly['order_createtime'] = $order_createtime;
    }

        if ($this->save($new_dly)){//创建大发货单
            if ($parents && is_array($parents))
            foreach ($parents as $p_id){
                $this->splitDelivery($p_id);
            }
            foreach ($new_ids as $id){
                $tmp_dly = array(
                    'delivery_id'=>$id,
                    'logi_no'=>null,
                    'parent_id'=>$new_dly['delivery_id']
                );
                $this->save($tmp_dly);
            }
            $this->insertParentItemByItems($new_dly['delivery_id'], $new_ids, $dly['branch_id']);//新增大发货单与小发货单的明细关联
            $this->insertParentOrderByItems($new_dly['delivery_id'], $new_ids);
            $this->insertParentItemDetailByItemsDetail($new_dly['delivery_id'], $new_ids);//2011.03.15新增（为发货单详情绑定订单商品关联）

            ////////////////////////////////为合并后的发货单生成统计字段///////////////////////////////////
            $bns = array();
            $totalNum = 0;
            $diObj = &$this->app->model('delivery_items');
            $dis = $diObj->getList('*', array('delivery_id'=>$new_dly['delivery_id']), 0, -1);
            foreach($dis as $v){
                $totalNum += $v['number'];
                $bns[$v['product_id']] = $v['bn'];
            }
            ksort($bns);
            //11.25新增
            $data['skuNum']     = count($dis);
            $data['itemNum']    = $totalNum;
            $data['bnsContent'] = serialize($bns);
            $data['idx_split']  = $data['skuNum'] * 10000000000 + sprintf("%u", crc32($data['bnsContent']));

            $data['delivery_id']     = $new_dly['delivery_id'];
            $this->save($data);
            /////////////////////////////////////////////////////////////////////////////////////////////////////

            $merge_dly = $this->getList("delivery_bn",array('delivery_id'=>$new_ids),0,-1);
            foreach($merge_dly as $v){
                $tmp_idd[] = $v['delivery_bn'];
            }
            $idd = implode(",",$tmp_idd);

            $opObj->write_log('delivery_merge@ome', $new_dly['delivery_id'], '合并发货单('.$idd.')');
            return true;
        }
        return false;
    }

    /**
     * 重置发货单
     * 使用：将发货单状态设置为初始状态 ，物流运单号设置为空
     *
     * @param array() $filter
     *
     * @return boolean
     */
    function resumeDelivery($filter){
        $rows = $this->getList('*', $filter, 0, -1);
        if (empty($rows)) return false;

        $dly_itemObj = &$this->app->model('delivery_items');
        foreach ($rows as $r){
            $data['parent_id']  = 0;
            $data['logi_no']    = NULL;
            if ($r['status'] == 'cancel' || $r['status'] == 'back'){
                $data['status'] = $r['status'];
            }else {
                $data['status']         = 'ready';
                $data['verify']         = 'false';
                $data['stock_status']   = 'false';
                $data['deliv_status']   = 'false';
                $data['expre_status']   = 'false';

                $dly_itemObj->resumeItemsByDeliveryId($r['delivery_id']);//重置每个发货单的校验
            }

            $filter2['delivery_id'] = $r['delivery_id'];

            $this->update($data, $filter2);
            $data = null;
        }
        return true;
    }

    /**
     * 调用model:delivery_items中的insertParentItemByItems方法
     * 作用：将子发货单的关联items复制给大发货单
     *
     * @param bigint $parent_id
     * @param array() $items
     *
     * @return boolean
     */
    function insertParentItemByItems($parent_id, $items, $branch_id){
        $dly_itemObj = &$this->app->model('delivery_items');
        return $dly_itemObj->insertParentItemByItems($parent_id, $items, $branch_id);
    }

    /**
     * 调用model:delivery_order中的insertParentOrderByItems方法
     * 作用：将子发货单的关联order复制给大发货单
     *
     * @param bigint $parent_id
     * @param array() $items
     *
     * @return boolean
     */
    function insertParentOrderByItems($parent_id, $items){
        $dly_orderObj = &$this->app->model('delivery_order');
        return $dly_orderObj->insertParentOrderByItems($parent_id, $items);
    }

    function insertParentItemDetailByItemsDetail($parent_id, $items){
        $didObj = &$this->app->model('delivery_items_detail');
        return $didObj->insertParentItemDetailByItemsDetail($parent_id, $items);
    }

    /**
     * 通过一个发货单号或一个发货单号数组，获取这些发货单号对应的订单号
     *
     * @param string/array() $dly_ids
     *
     * @return array()                  订单ID的数组(自然下标)
     */
    function getOrderIdByDeliveryId($dly_ids){
        $dly_orderObj = &$this->app->model('delivery_order');
        $filter['delivery_id'] = $dly_ids;

        $data = $dly_orderObj->getList('order_id', $filter);
        foreach ($data as $item){
            $ids[] = $item['order_id'];
        }
        return $ids;
    }

    /**
     * 通过发货单号获取发货单详情关联表的对应记录
     *
     * @param bigint $dly_id
     *
     * @return array()
     */
    function getItemsByDeliveryId($dly_id){
        $dly_itemObj = &$this->app->model('delivery_items');
        $rows = $dly_itemObj->getList('*', array('delivery_id' => $dly_id),0,-1);

        return $rows;
    }

    /**
     * 通过仓库ID和货品ID，获取其所有货位的商品数量信息
     *
     * @param int $branch_id
     * @param int $product_id
     *
     * @return array()
     * ss备注：些方法已经没用，可以删除
     */
    function getBranchProductPosNum($branch_id, $product_id){
        //$branch_pposObj = &$this->app->model('branch_product_pos');
        //$rows = $branch_pposObj->getList('*', array('branch_id' => $branch_id, 'product_id' => $product_id));
        $sql = "SELECT * FROM sdb_ome_branch_product_pos dpp
                               JOIN sdb_ome_branch_pos dp
                                   ON dpp.pos_id=dp.pos_id
                               WHERE dp.branch_id='$branch_id' AND dpp.product_id='$product_id'";

        return $this->db->select($sql);
    }

    /**
     * 通过发货单的itemId获取其相应的item货位商品数量信息
     *
     * @param int $item_id
     *
     * @return array()
     * ss备注：些方法已经没用，可以删除
     */
    function getItemPosByItemId($item_id){
        $dly_iposObj = &$this->app->model('dly_items_pos');
        $branch_posObj = &$this->app->model('branch_pos');
        $rows = $dly_iposObj->getList('*', array('item_id' => $item_id));
        foreach ($rows as $key => $item){//循环取出货位名称
            $pos = $branch_posObj->dump($item['pos_id']);
            $rows[$key]['store_position'] = $pos['store_position'];
        }
        return $rows;
    }

    /**
     * 通过delivery_id(可以为数组)删除发货单订单关联表中的记录
     *
     * @param bigint/array() $dly_id
     *
     * @return boolean
     */
    function deleteDeliveryItemDetailByDeliveryId($dly_id){
        if ($dly_id){
            $didObj = &$this->app->model('delivery_items_detail');
            $filter['delivery_id'] = $dly_id;
            return $didObj->delete($filter);
        }
        return false;
    }
    /**
     * 通过delivery_id(可以为数组)删除发货单订单关联表中的记录
     *
     * @param bigint/array() $dly_id
     *
     * @return boolean
     */
    function deleteDeliveryOrderByDeliveryId($dly_id){
        if ($dly_id){
            $dly_orderObj = &$this->app->model('delivery_order');
            $filter['delivery_id'] = $dly_id;
            return $dly_orderObj->delete($filter);
        }
        return false;
    }

    /**
     * 通过delivery_id(可以为数组)删除发货单明细关联表中的记录
     *
     * @param bigint/array() $dly_id
     *
     * @return boolean
     */
    function deleteDeliveryItemsByDeliveryId($dly_id){
        if ($dly_id){
            $dly_itemObj = &$this->app->model('delivery_items');
            $filter['delivery_id'] = $dly_id;
            return $dly_itemObj->delete($filter);
        }
        return false;
    }

    /**
     * 删除发货单相关的货位信息（只有合并过的发货单才会触发此方法）
     *
     * @param int $dly_id
     *
     * @return boolean
     * ss备注：此方法可以被删除
     */
    function deleteDeliveryItemsPosByDeliveryId($dly_id){
        if ($dly_id){
            $dly_itemObj = &$this->app->model('delivery_items');
            $dly_itemPosObj = &$this->app->model('dly_items_pos');
            foreach ($dly_id as $id){
                $rows = $dly_itemObj->getList('*', array('delivery_id'=>$id), 0, -1);
                if (empty($rows)) return false;
                foreach ($rows as $row){
                    $filter['item_id'] = $row['item_id'];
                    $dly_itemPosObj->delete($filter);
                }
            }
            return true;
        }
        return false;
    }

    /**
     * 打回发货单操作
     *
     * @param array() $dly_ids
     * @param string $memo
     * @param boolean $reback_status 打回状态，默认为false:打回所有发货单;true：只打回未发货的发货单
     * @return boolean
     */
    function rebackDelivery($dly_ids, $memo, $dly_status=false){
        if (is_array($dly_ids)){
            $ids = $dly_ids;
        }else {
            $ids[] = $dly_ids;
        }
        $data['memo']        = $memo;
        $data['status']      = 'back';
        $orderObj = &$this->app->model('orders');
        $delivery_itemsObj = &$this->app->model('delivery_items');
        $branch_productObj = &$this->app->model('branch_product');
        foreach ($ids as $item){
            $delivery_detail = $this->dump($item,'status');
            if ($delivery_detail['status'] == 'succ' ) continue;
            $data['delivery_id'] = $item;
            //增加branch_product释放冻结库存
            $branch_id = $this->getList('branch_id',array('delivery_id'=>$data['delivery_id']),0,-1);
            $product_ids = $delivery_itemsObj->getList('product_id,number',array('delivery_id'=>$data['delivery_id']),0,-1);
            foreach($product_ids as $key=>$v){
                $branch_productObj->unfreez($branch_id['0']['branch_id'],$v['product_id'],$v['number']);
            }

            //将发货单状态更新为打回并记录备注
            if ($this->save($data)){
                if (!$dly_status){
                    $order = $this->getOrderIdByDeliveryId($item);
                    if ($this->validDeiveryByOrderId($order[0])){
                        $order_status = 'splitting';
                        $orderObj->set_status($order[0], $order_status);//将订单状态更新为拆分中
                    }else {
                        $order_status = 'confirmed';
                        $orderObj->set_status($order[0], $order_status);//将订单状态更新为拆分中
                    }
                }
            }
            //打回发货单状态同步
            if ($service_delivery = kernel::servicelist('service.delivery')){
                foreach($service_delivery as $object=>$instance){
                    if(method_exists($instance, 'update_status')){
                        $instance->update_status($data['delivery_id'], 'cancel');
                    }
                }
            }
        }
        return true;
    }

    function validDeiveryByOrderId($order_id){
        $sql = "SELECT COUNT(*) AS _count FROM sdb_ome_delivery_order do
                                JOIN sdb_ome_delivery d
                                    ON do.delivery_id=d.delivery_id
                                WHERE do.order_id=$order_id
                                    AND d.parent_id=0
                                    AND d.status IN ('ready','progress','succ')
                                    AND d.disabled='false'";
        $row = $this->db->selectrow($sql);
        if ($row['_count'] > 0) return true;
        return false;
    }

    function getCorpsByBranchId(){

    }

    /**
     * 获取发货人信息
     *
     * @param int $dly_id
     *
     * @return array()
     */
    function getShopInfo($shop_id){
        /*$sql = "SELECT s.* FROM sdb_ome_delivery_order do
                               JOIN sdb_ome_orders o
                                   ON do.order_id=o.order_id
                               JOIN sdb_ome_shop s
                                   ON o.shop_id=s.shop_id
                              WHERE do.delivery_id='$dly_id'";

        //$shop = $this->db->selectrow($sql);*/
        $shopObj = &$this->app->model("shop");
        $shop = $shopObj->dump($shop_id);
        return $shop;
    }

    /**
     * 统计商品数量
     *
     * @param array() $dly_ids
     *
     * @return array()
     */
    function countProduct($dly_ids=null){
        if ($dly_ids){
        $sql = "SELECT bn,product_name,SUM(number) AS 'count' FROM sdb_ome_delivery_items
                                                              WHERE delivery_id IN ($dly_ids) AND number!=0 GROUP BY bn";

        $data = $this->db->select($sql);
        }
        return $data;
    }

    /**
     * 统计商品在每个货位上的数量
     *
     * @param array() $dly_ids
     * @param string $bn
     *
     * @return array()
     * ss备注：此方法已经没用，可以删除
     */
    function countProductPos($dly_ids=null, $bn=null){
        if ($dly_ids){
        $sql = "SELECT bp.store_position,SUM(dip.num) AS 'count' FROM sdb_ome_delivery_items di
                                JOIN sdb_ome_dly_items_pos dip
                                    ON di.item_id=dip.item_id
                                JOIN sdb_ome_branch_pos bp
                                    ON dip.pos_id=bp.pos_id
                                WHERE di.delivery_id IN ($dly_ids)
                                    AND di.number!=0
                                    AND dip.num!=0 AND di.bn='$bn'
                                GROUP BY di.bn,bp.store_position";

        $rows = $this->db->select($sql);
        }
        return $rows;
    }

    function getProductPosByDeliveryId($dly_id=null){
        if ($dly_id){
        $sql = "SELECT di.bn,di.product_name,
                        di.number,delivery_id,
                        p.spec_info,p.name, bp.store_position FROM sdb_ome_delivery_items di
                                JOIN sdb_ome_products p
                                    ON p.product_id=di.product_id
                                LEFT JOIN (
                                SELECT bpp.*
                                FROM (
                                SELECT pos_id,product_id
                                FROM sdb_ome_branch_product_pos
                                ORDER BY create_time DESC
                                )bpp
                                GROUP BY bpp.product_id
                                )bb
                                ON bb.product_id = di.product_id
                                LEFT JOIN sdb_ome_branch_pos bp ON bp.pos_id = bb.pos_id
                                WHERE di.delivery_id = $dly_id
                                    AND di.number != 0";

        $rows = $this->db->select($sql);
        }
        return $rows;
    }

    function getOrderMemoByDeliveryId($dly_ids=null){
        if ($dly_ids){
            $sql = "SELECT o.custom_mark FROM sdb_ome_delivery_order do
                                    JOIN sdb_ome_orders o
                                        ON do.order_id=o.order_id
                                    WHERE do.delivery_id IN ($dly_ids)
                                        GROUP BY do.order_id ";
            $rows = $this->db->select($sql);
            $memo = array();
            if ($rows){
                foreach ($rows as $v)
                $memo[] = unserialize($v['custom_mark']);
            }
            return serialize($memo);
        }
    }

    /**
     * 统计订单商品的发货数量
     *
     * @param int $order_id
     *
     * @return int
     */
    function countOrderSendNumber($order_id){
        $sql = "SELECT COUNT(*) AS 'total' FROM sdb_ome_order_items WHERE order_id = '$order_id' AND nums!=sendnum AND `delete`='false'";
        $item_num = $this->db->selectrow($sql);
        return $item_num['total'];
    }

    /**
     * 更新商品表商品数量
     *
     * @param int $num
     * @param int $product_id
     *
     * @return boolean
     *
    function updateProduct($num, $product_id){
        $oProducts = &$this->app->model("products");
        $oProducts->chg_product_store($product_id,$num,"-");
        $oProducts->chg_product_store_freeze($product_id,$num,"-");
    }

    /**
     * 更新仓库商品表商品数量
     *
     * @param int $num
     * @param int $product_id
     * @param int $branch_id
     *
     * @return boolean
     *
    function updateBranchProduct($num, $product_id, $branch_id){
        $now = time();
        //$sql = "UPDATE sdb_ome_branch_product SET store=store-$num,store_freeze=store_freeze-$num,last_modified=$now WHERE branch_id='$branch_id' AND product_id='$product_id'";
        //暂时不在branch_product上使用冻结库存
        $sql = "UPDATE sdb_ome_branch_product SET store=store-$num,last_modified=$now WHERE branch_id='$branch_id' AND product_id='$product_id'";
        //echo $sql;
        return $this->db->exec($sql);//扣减branch_product表
    }

    /**
     * 更新仓库商品货位表商品数量
     *
     * @param int $num
     * @param int $product_id
     * @param int $pos_id
     *
     * @return boolean
     *
    function updateBranchProductPos($num, $product_id, $pos_id){
         $sql = "UPDATE sdb_ome_branch_product_pos SET store=store-$num WHERE pos_id='$pos_id' AND product_id='$product_id'";
         //echo $sql;
         return $this->db->exec($sql);//扣减branch_product_pos表
    }/*

     /*
     * 生成发货单号
     *
     *
     * @return bigint           发货单号
     */
    function gen_id(){
        $cManage = &$this->app->model("concurrent");
        $prefix = date("ymd").'11';
        $sqlString = "SELECT MAX(delivery_bn) AS maxno FROM sdb_ome_delivery WHERE delivery_bn LIKE '".$prefix."%'";
        $aRet = $this->db->selectrow($sqlString);
        if(is_null($aRet['maxno'])){
        	$aRet['maxno'] = 0;
        	$maxno = 0;
        }else
            $maxno = substr($aRet['maxno'], -5);

        do{
            $maxno += 1;
            if ($maxno==100000){
                break;
            }
            $maxno = str_pad($maxno,5,'0',STR_PAD_LEFT);

            $sign = $prefix.$maxno;

            if($cManage->is_pass($sign,'delivery')){
                break;
            }
        }while(true);

        return $sign;
    }

    /*
     * 根据订单id获取发货单信息
     *
     * @param string $cols
     * @param bigint $order_id 订单id
     *
     * @return array $delivery 发货单数组
     */
    function getDeliveryByOrder($cols="*",$order_id){
        $delivery_ids = $this->getDeliverIdByOrderId($order_id);
        if($delivery_ids){
            $f_status = array('ready','progress','succ');
            $delivery = $this->getList($cols,array('delivery_id'=>$delivery_ids,'status'=>$f_status),0,-1);
            if($delivery){
                foreach($delivery as $k=>$v){
                    if(isset($v['logi_id'])){
                        $dly_corp = $this->db->selectrow("SELECT * FROM sdb_ome_dly_corp WHERE disabled='false' AND corp_id=".intval($v['logi_id']));
                        $delivery[$k]['request_url'] = $dly_corp['website'];//TODO: 等request_url完善后使用request_url
                    }

                    if(isset($v['branch_id'])){
                      $branch = $this->db->selectrow("SELECT * FROM sdb_ome_branch WHERE disabled='false' AND branch_id=".intval($v['branch_id']));
                      $delivery[$k]['branch_name'] = $branch['name'];
                    }

                    if(isset($v['status'])){
                        if(empty($status_text))
                            $status_text = array ('succ' => '已发货','failed' => '发货失败','cancel' => '已取消','progress' => '等待配货','timeout' => '超时','ready' => '等待配货','stop' => '暂停','back' => '打回');

                        $delivery[$k]['status_text'] = $status_text[$v['status']];
                    }

                    if(isset($v['stock_status']) || isset($v['deliv_status']) || isset($v['expre_status'])){
                        if($v['stock_status'] == 'ture' && $v['deliv_status'] == 'true' && $v['expre_status'] == 'true'){
                            $delivery[$k]['print_statis'] = '已完成打印';
                        }else if($v['stock_status'] == 'false' && $v['deliv_status'] == 'false' && $v['expre_status'] == 'false'){
                            $delivery[$k]['print_status'] = '未打印';
                        }else{
                            if($v['stock_status'] == 'true'){
                                $print_status[] = '备货单';
                            }
                            if($v['deliv_status'] == 'true'){
                                $print_status[] = '清单';
                            }
                            if($v['expre_status'] == 'true'){
                                $print_status[] = '快递单';
                            }
                            $delivery[$k]['print_status'] = implode("/",$print_status)."已打印";
                        }
                    }
                }
                return $delivery;
            }else{
                return array();
            }
        }else{
            return array();
        }
    }

    /*
     * 根据订单id获取发货单id
     * 只获取父id是0的发货单
     *
     * @param bigint $order_id
     *
     * @return array $ids
     */
    function getDeliverIdByOrderId($order_id){
        $delivery_ids = $this->db->select("SELECT dord.delivery_id FROM sdb_ome_delivery_order AS dord
                                            LEFT JOIN sdb_ome_delivery AS d ON(dord.delivery_id=d.delivery_id)
                                            WHERE dord.order_id={$order_id} AND (d.parent_id=0 OR d.is_bind='true') AND d.disabled='false' AND d.status NOT IN('failed','cancel','back')");
        $ids = array();
        if($delivery_ids){
            foreach($delivery_ids as $v){
                $ids[] = $v['delivery_id'];
            }
        }
        return $ids;
    }

    /**
     * 根据发货单ID判断相关订单ID所有相关联的发货单是否都已打印，如果都打印，更新订单print_finish为TRUE
     * $type为0 是否更新，为1时，更新为FALSE
     *
     * @param bigint $dly_id
     * @param int $type
     *
     */
    function updateOrderPrintFinish($dly_id, $type=0){
        $orderIds = $this->getOrderIdByDeliveryId($dly_id);
        foreach ($orderIds as $id){
            if ($type == 0){
                $flag = 0;
                $dlyIds = $this->getDeliverIdByOrderId($id);
                foreach ($dlyIds as $i){
                    $dly = $this->dump($i);
                    if ($dly['stock_status'] == 'false') break;
                    if ($dly['deliv_status'] == 'false') break;
                    if ($dly['expre_status'] == 'false') break;
                    $flag++;
                }
                if ($flag > 0){
                    $ordObj = &$this->app->model('orders');
                    $data['order_id'] = $id;
                    $data['print_finish'] = 'true';
                    $ordObj->save($data);

                }
            }elseif ($type == 1){
                $ordObj = &$this->app->model('orders');
                $data['order_id'] = $id;
                $data['print_finish'] = 'false';
                $ordObj->save($data);
            }
        }
        return true;
    }

    /*
     * 根据发货单来还原货品的冻结库存
     *
     * @param int $delivery_id 发货单id
     *
     * @return bool
     */
    function unfreez($delivery_id){
        $sdf_delivery = $this->dump($delivery_id,"delivery_id,branch_id",array('delivery_items'=>array("product_id,number")));
        if($sdf_delivery['delivery_items']){
            $oProduct = &$this->app->model("products");
            foreach($sdf_delivery['delivery_items'] as $v){
                $oProduct->unfreez($sdf_delivery['branch_id'],$v['product_id'],$v['number']);
            }
        }
    }

    /*
     * 设置发货单状态
     *
     * @param int $delivery_id
     * @param string $status 状态
     *
     * @return bool
     */
    function set_status($delivery_id,$status){
        $data = array(
           'delivery_id' => $delivery_id,
           'status' => $status,
        );
        return $this->save($data);
    }


    /*
     * 获取订单已生成发货单的货品数量
     *
     * @param bigint $order_id 订单id
     * @param int $product_id 货品id
     *
     * @return int
     */
    function getDeliveryFreez($order_id,$product_id){
        $sql = "SELECT SUM(di.number) AS nums FROM sdb_ome_delivery_order AS dord
                    LEFT JOIN sdb_ome_delivery AS d ON(dord.delivery_id=d.delivery_id)
                    LEFT JOIN sdb_ome_delivery_items AS di ON(di.delivery_id=d.delivery_id)
                    WHERE dord.order_id={$order_id} AND di.product_id={$product_id} AND d.parent_id=0 AND d.disabled='false' AND d.status IN('succ','failed','progress','timeout','ready','stop')";

        $ret = $this->db->selectrow($sql);

        return $ret['nums'];
    }

    /*
     * 获取发货单可以合并的依据
     *
     * @param int $shop_id 前端店铺id
     * @param int $branch_id 仓库id
     * @param string $ship_addr 收货地址
     * @param int $member_id 会员id
     * @param string $is_cod 是否活到付款 true/false
	 * @param string $is_protect 是否保价 true/false
     *
     * @return string
     */
    function getBindKey($data){
     
		    kernel::log(json_encode($data));
        $bindkey = md5($data['shop_id'].$data['branch_id'].$data['consignee']['addr'].$data['member_id'].$data['is_cod'].$data['is_protect']);
        if ($service = kernel::service('ome.service.delivery.bindkey')){
            if (method_exists($service, 'get_bindkey')){
                $bindkey = $service->get_bindkey($data);
            }
        }

        return $bindkey;
    }

    /*
     * 新建发货单
     *
     * @param bigint $order_id 订单id
     * $order
     * @param array $ship_info 收货人相关信息
     *                          array(
     *                              'name' => xxx,
     *                              'area' => xxx,
     *                              'addr' => xxx,
     *                              'zip' => xxx,
     *                              'telephone' => xxx,
     *                              'mobile' => xxx,
     *                              'email' => xxx,
     *                          )
     *
     * @return $int $delivery_id 发货单id
     */
    function addDelivery($order_id,$delivery,$ship_info=array(),$order_items=array()){
        $branch_productObj = &$this->app->model("branch_product");
        $oOrder = &$this->app->model("orders");
        $oDly_corp = &$this->app->model("dly_corp");
        //$oDly_items_pos = &$this->app->model("dly_items_pos");
        
        //开启添加发货单事务,锁定当前订单记录
        $this->db->exec('begin');
        $this->db->exec('select order_id from sdb_ome_orders where order_id='.$order_id.' for update');

        $is_null = true;
        $item_list = $oOrder->getItemBranchStore($order_id);
        if ($item_list)
        foreach ($item_list as $il){
            if ($il)
            foreach ($il as $var){
                if ($var)
                foreach ($var['order_items'] as $v){
                    if ($v['left_nums'] > 0){
                        $is_null = false;
                    }
                }
            }
        }
        if ($is_null == true){
            trigger_error("无商品需要拆分", E_USER_ERROR);
            return false;
        }
        //增加branch_product的冻结库存
        foreach($delivery['delivery_items'] as $key=>$items){
            $sql = "SELECT (store-store_freeze) AS 'has' FROM sdb_ome_branch_product WHERE branch_id=".intval($delivery['branch_id'])." AND product_id=".$items['product_id'];
            $branch_p = $this->db->selectrow($sql);
            if (!is_numeric($items['number'])){
                trigger_error($items['product_name'].":请输入正确数量", E_USER_ERROR);
                return false;
            }
            if (empty($branch_p['has']) || $branch_p['has'] == 0 ||  $branch_p['has'] < $items['number']) {
                trigger_error($items['product_name'].":商品库存不足", E_USER_ERROR);
                return false;
            }
            $branch_productObj->freez($delivery['branch_id'],$items['product_id'],$items['number']);
        }

        $order = $oOrder->dump($order_id);
        if($delivery['consignee']){
            $ship_info = $delivery['consignee'];
        }else if($order_id){
           if (empty($ship_info)){
               $ship_info = $order['consignee'];
           }
        }

        $t_area = explode(":",$ship_info['area']);
        $m_area = explode("/",$t_area[1]);
        $weight = 0;
        if (empty($delivery['delivery_bn'])){
            $delivery_bn = $this->gen_id();
        }else {
            $delivery_bn = $delivery['delivery_bn'];
        }

        $data['delivery_bn'] = $delivery_bn;
        $is_protect = $delivery['is_protect']?$delivery['is_protect']:$order['shipping']['is_protect'];
//        if($is_protect){
//            $data['is_protect'] = $is_protect;
//        }
        $is_cod = $delivery['is_cod']?$delivery['is_cod']:$order['shipping']['is_cod'];
        if($is_cod){
            $data['is_cod'] = $is_cod;
        }

        $data['delivery'] = $delivery['delivery']?$delivery['delivery']:$order['shipping']['shipping_name'];
        $data['logi_id'] = $delivery['logi_id'];
        $data['memo'] = $delivery['memo'];
        $data['branch_id'] = $delivery['branch_id'];
        if($delivery['type']){
            $data['type'] = $delivery['type'];
        }

        foreach($delivery['delivery_items'] as $k=>$item){
            $p_weight = $this->db->selectrow("SELECT weight FROM sdb_ome_products WHERE product_id=".$item['product_id']);
            $weight += $p_weight['weight'] * $item['number'];
        }
        $corp  = $oDly_corp->dump($delivery['logi_id']);//物流公司信息
        //计算预计物流费用
        $area = $delivery['consignee']['area'];
        $arrArea = explode(':', $area);
        $area_id = $arrArea[2];
        if (isset($corp['area_fee_conf']) && $corp['area_fee_conf']){
            $area_fee_conf = unserialize($corp['area_fee_conf']);
            foreach($area_fee_conf as $k=>$v){
                 $areas = explode(',',$v['areaGroupId']);

                 // 再次解析字符
                  foreach ($areas as &$strArea){
                    if (strpos($strArea, '|') !== false){
                       $strArea = substr($strArea, 0, strpos($strArea, '|'));
                        // 取当前area id对应的最上级的区域id
                        $objRegions = app::get('ectools')->model('regions');
                        $arrRegion = $objRegions->dump($area_id);
                        while ($row = $objRegions->getRegionByParentId($arrRegion['p_region_id'])){
                             $arrRegion = $row;
                             $tmp_area_id = $row['region_id'];
                             if ($tmp_area_id == $strArea){
                                $area_id = $tmp_area_id;
                                        break;
                                    }
                                }
                            }
                        }

                        if(in_array($area_id,$areas))
                        {
                            //如果地区在其中，优先使用地区设置的配送费用，及公式
                            $corp['firstprice'] = $v['firstprice'];
                            $corp['continueprice'] = $v['continueprice'];
                            $corp['dt_expressions'] = $v['dt_expressions'];
                            break;
                        }
                    }
         }
        $price = utils::cal_fee($corp['dt_expressions'], $weight, 0,$corp['firstprice'],$corp['continueprice']); //TODO 生成快递费用
        $logi_name = "";
        if($delivery['logi_id']){
            $dly_corp = $oDly_corp->dump($delivery['logi_id']);
            $logi_name = $dly_corp['name'];
            //计算保价费用
            $protect = $dly_corp['protect'];
            if($protect == 'true'){
                $is_protect = 'true';
                $protect_rate = $dly_corp['protect_rate'];//保价费率
                $protect_price = $protect_rate * $weight;
                $minprice = $dly_corp['minprice'];//最低报价费用
                if($protect_price < $minprice){
                    $cost_protect = $minprice;
                }else{
                    $cost_protect = $protect_price;
                }
            }
        }
        $data['logi_name'] = $logi_name;
        $data['is_protect'] = $is_protect ? $is_protect : 'false';
        $data['create_time'] = time();
        $data['cost_protect'] = $cost_protect ? $cost_protect :'0';
        $data['net_weight'] = $weight;
        $data['delivery_cost_expect'] = $price;
        $data['member_id'] = $delivery['member_id']?$delivery['member_id']:$order['member_id'];
        $data['shop_id'] = $order['shop_id'];

        $data['delivery_items'] = $delivery['delivery_items'];

        $data['consignee'] = $ship_info;
        $data['consignee']['province'] = $m_area[0];
        $data['consignee']['city'] = $m_area[1];
        $data['consignee']['district'] = $m_area[2];

        $data['order_createtime'] = $order['createtime'];

        $opInfo = kernel::single('ome_func')->getDesktopUser();
        $data['op_id'] = $opInfo['op_id'];
        $data['op_name'] = $opInfo['op_name'];

        $bns = array();
        $totalNum = 0;
        foreach($data['delivery_items'] as $v){
            $totalNum += $v['number'];
            $bns[$v['product_id']] = $v['bn'];
        }
        ksort($bns);
        //11.25新增
        $data['skuNum']     = count($delivery['delivery_items']);
        $data['itemNum']    = $totalNum;
        $data['bnsContent'] = serialize($bns);
        $data['idx_split']  = $data['skuNum'] * 10000000000 + sprintf("%u", crc32($data['bnsContent']));

        $data['bind_key'] = $this->getBindKey($data);
        $this->save($data);
        
    	if($data['delivery_id']){
        	$this->db->commit();
        }else{
        	$this->db->rollBack();
        	return false;
        }
        
        /*foreach($data['delivery_items'] as $item){
            $pos = $this->db->selectrow("SELECT bp.pos_id FROM sdb_ome_branch_pos AS bp LEFT JOIN sdb_ome_branch_product_pos AS bpp ON(bpp.pos_id=bp.pos_id) WHERE bp.branch_id=".intval($delivery['branch_id'])." AND bpp.product_id=".$item['product_id']." AND bpp.default_pos='true'");
            if (empty($pos['pos_id'])) {
                trigger_error($item['product_name'].":无默认货位", E_USER_ERROR);
                return false;
            }
            $pos_id = $pos['pos_id'];
            $items_pos = array('item_id'=>$item['item_id'],'pos_id'=>$pos_id,'num'=>$item['number']);

            $oDly_items_pos->save($items_pos);
        }*/
        if ($data['delivery_id'] && !empty($order_items) && is_array($order_items)){
            $this->create_delivery_items_detail($data['delivery_id'], $order_items);
        }

        //调用合并发货单的app
        if ($data['delivery_id']){
            if($obind = kernel::service('create_delivery_bind')){
                $dly = $this->dump($data['delivery_id']);
                if(method_exists($obind,'create')){
                    $obind->create($dly);
                }
            }
        }

        //插关联表
        if($order_id){
            $rs = $this->db->exec('SELECT * FROM sdb_ome_delivery_order WHERE 0=1');
            $ins = array('order_id'=>$order_id,'delivery_id'=>$data['delivery_id']);
            $sql = kernel::single("base_db_tools")->getinsertsql($rs,$ins);
            $this->db->exec($sql);
        }

        if($oAutobind = kernel::service('do_autobind')){
            $dly = $this->dump($data['delivery_id']);
            if(method_exists($oAutobind,'autobind')){
                $oAutobind->autobind($dly);
            }
        }

        //发货单创建
        foreach(kernel::servicelist('service.delivery') as $object=>$instance){
            if(method_exists($instance,'delivery')){
                $instance->delivery($data['delivery_id']);
            }
        }

        return $data['delivery_id'];
    }

    function create_delivery_items_detail($delivery_id,$order_items){
        $didObj = &$this->app->model('delivery_items_detail');
        $diObj = &$this->app->model('delivery_items');
        $oiObj = &$this->app->model('order_items');
        foreach ($order_items as $item){
            $oi = $oiObj->dump($item['item_id']);
            $di = $diObj->dump(array('delivery_id'=>$delivery_id,'product_id'=>$item['product_id']));
            $did = array(
                'delivery_id'       => $delivery_id,
                'delivery_item_id'  => $di['item_id'],
                'order_id'          => $oi['order_id'],
                'order_item_id'     => $oi['item_id'],
                'order_obj_id'      => $oi['obj_id'],
                'item_type'         => $oi['item_type'],
                'product_id'        => $oi['product_id'],
                'bn'                => $oi['bn'],
                'number'            => $item['number'],
                'price'             => $oi['price'],
                'amount'            => $item['number']*$oi['price'],
            );
            $didObj->save($did);
        }
    }

    function call_delivery_api($delivery_id){
        $shopObj = &app::get('ome')->model('shop');
        $delivery_info = $this->dump($delivery_id);
        $shop_detail = $shopObj->dump($delivery_info['shop_id'], 'node_type');
        $foreground_shop_list = ome_shop_type::shop_list();
        if($delivery_info['is_bind'] == 'true' and !in_array($shop_detail['node_type'],$foreground_shop_list)){
            $delivery_ids = $this->getItemsByParentId($delivery_id,'array');
            foreach($delivery_ids as $v){
                $this->_call_shipping_api($v);
            }
        }else{
            $this->_call_shipping_api($delivery_id);
        }
    }

    function _call_shipping_api($delivery_id){
        $order = $this->db->selectrow("SELECT order_id FROM sdb_ome_delivery_order WHERE delivery_id=".$delivery_id);
        $order_id = $order['order_id'];

        //发货API
        foreach(kernel::servicelist('service.delivery') as $object=>$instance){
            if(method_exists($instance,'delivery')){
                $instance->delivery($delivery_id);
            }
        }

        //更新发货单状态 API
        foreach(kernel::servicelist('service.delivery') as $object=>$instance){
            if(method_exists($instance,'update_status')){
                $instance->update_status($delivery_id, '', true);
            }
        }
        //更新订单发货状态 API
        foreach(kernel::servicelist('service.order') as $object=>$instance){
            if(method_exists($instance, 'update_ship_status')){
                $instance->update_ship_status($order_id, true);
            }
        }
    }

    function array2xml2($data,$root='root'){
        $xml='<'.$root.'>';
        $this->_array2xml($data,$xml);
        $xml.='</'.$root.'>';
        return $xml;
    }

    function _array2xml(&$data,&$xml){
        if(is_array($data)){
            foreach($data as $k=>$v){
                if(is_numeric($k)){
                    $xml.='<item>';
                    $xml.=$this->_array2xml($v,$xml);
                    $xml.='</item>';
                }else{
                    $xml.='<'.$k.'>';
                    $xml.=$this->_array2xml($v,$xml);
                    $xml.='</'.$k.'>';
                }
            }
        }elseif(is_numeric($data)){
            $xml.=$data;
        }elseif(is_string($data)){
            $xml.='<![CDATA['.$data.']]>';
        }
    }

    function existStockIsPlus($product_id, $store, $item_id, $branch_id, &$err_msg, $bn){
        $err_msg = '';
        $branch_pObj = &$this->app->model("branch_product");
        /*$dly_ipObj = &$this->app->model("dly_items_pos");
        $branch_ppObj = &$this->app->model("branch_product_pos");
        $pObj = &$this->app->model("products");
        $dly_ip = $dly_ipObj->getList('*',array('item_id'=>$item_id),0,-1);
        if (empty($dly_ip)){
            $err_msg = $bn."：此货号商品货位关联无效";
            return false;
        }*/
        $bp = $branch_pObj->dump(array('branch_id'=>$branch_id,'product_id'=>$product_id),'store');
        if ($bp['store'] < $store){
            $err_msg = $bn."：此货号商品仓库商品数量不足";
            return false;
        }
        return true;
    }
    /*
     * 校验发货单
     */
    function verifyDelivery($dly){
        $dly_id = $dly['delivery_id'];
        $dly_itemObj  = &$this->app->model('delivery_items');
        $opObj        = &$this->app->model('operation_log');
        //对发货单详情进行校验完成处理
        if ($dly_itemObj->verifyItemsByDeliveryId($dly_id)){
            $delivery['delivery_id'] = $dly_id;
            $delivery['verify'] = 'true';

            if (!$this->save($delivery)) return false;

            if($dly['is_bind'] == 'true'){
                $ids = $this->getItemsByParentId($dly_id, 'array');
                foreach ($ids as $i){
                    $dly_itemObj->verifyItemsByDeliveryId($i);
                }
            }

            if (kernel::single('desktop_user')->get_id()) $opObj->write_log('delivery_check@ome', $dly_id, '发货单校验完成');
            return true;
        }else {

            if (kernel::single('desktop_user')->get_id()) $opObj->write_log('delivery_check@ome', $dly_id, '发货单校验未完成');
            return false;
        }
    }

    function queueConsign($delivery_id){
        $oQueue = &app::get('base')->model('queue');
        $queueData = array(
            'queue_title'=>'订单导入',
            'start_time'=>time(),
            'params'=>array(
                'sdfdata'=>$delivery_id,
                'app' => 'ome',
                'mdl' => 'delivery'
            ),
            'worker'=>'ome_delivery_consign.run',
        );
        $oQueue->save($queueData);
    }

    /*
     * 处理订单发货数量
     */
    function consignOrderItem($delivery){
        $ord_itemObj = &$this->app->model('order_items');
        $didObj = &$this->app->model('delivery_items_detail');
        /*$de = $delivery['delivery_order'];
        $or = array_shift($de);
        $ord_id = $or['order_id'];
        unset($de);*/
        //$order_items = $ord_itemObj->getList('*',array('order_id'=>$ord_id,'delete'=>'false'),0,-1);
        if (!empty($delivery['delivery_items'])){
            foreach ($delivery['delivery_items'] as $r){
                $filter = array(
                    'delivery_item_id' => $r['item_id'],
                    'product_id' => $r['product_id'],
                );
                $rows = $didObj->getList('*', $filter, 0, -1);

                if ($rows)
                foreach ($rows as $row){
                    $num = (int)$row['number'];
                    $sql = "UPDATE sdb_ome_order_items SET sendnum = IFNULL(sendnum,0)+".$num." WHERE item_id=".$row['order_item_id'];
                    $this->db->exec($sql);
                }
            }
        }
    }

    /*
     * 完成发货
     */
    function consignDelivery($dly_id, $weight=0, &$msg){

        $delivery_time = time();
        //出入库及销售单记录
        $iostock_sales_set_result = true;
        $iostock_sales_data = array();
        $iostock_data = kernel::single('ome_iostocksales')->get_iostock_data($dly_id);
        $sales_data = kernel::single('ome_iostocksales')->get_sales_data($dly_id);
        
        //获取物流费用
        $delivery_cost_actual = $this->getDeliveryCost($dly_id,$weight);
        $sales_data['delivery_cost_actual'] = $delivery_cost_actual;
        $iostock_sales_data['iostock'] = $iostock_data;
        $iostock_sales_data['sales'] = $sales_data;
        if ( $iostock_sales_service = kernel::service('ome.service.iostock_sales') ){
            if ( method_exists($iostock_sales_service, 'set') ){
                $io = '0';//出入库类型：0出库1入库
                $iostock_sales_set_result = $iostock_sales_service->set($iostock_sales_data, $io, $msg);
            }
        }
        if ( $iostock_sales_set_result ){

            $dly = $this->dump($dly_id,'*',array('delivery_items'=>array('*'),'delivery_order'=>array('*')));
            $orderObj    = &$this->app->model('orders');
            $ord_itemObj = &$this->app->model('order_items');
            $opObj       = &$this->app->model('operation_log');
            //判断发货单类型，如果是合并发货单，处理逻辑分开
            if ($dly['is_bind'] == 'true'){
                /*
                 * 合并发货单，发货处理
                 */
                $ids = $this->getItemsByParentId($dly['delivery_id'],'array');
                foreach ($ids as $item){
                    $delivery = $this->dump($item,'delivery_id,type',array('delivery_items'=>array('*'),'delivery_order'=>array('*')));

                    $de = $delivery['delivery_order'];
                    $or = array_shift($de);
                    $ord_id = $or['order_id'];
                    if ($delivery['type'] == 'normal'){//如果不为售后生成的发货单，才进行订单发货数量的更新
                        $this->consignOrderItem($delivery);
                    }
                    $dlydata['delivery_id'] = $delivery['delivery_id'];
                    $dlydata['process']     = 'true';
                    $dlydata['status'] = 'succ';
                    $dlydata['delivery_time'] = $delivery_time;
                    $this->save($dlydata);//更新子发货单发货状态为已发货
                    $item_num = $this->countOrderSendNumber($ord_id);

                    $orderdata['order_id'] = $ord_id;
                    if ($item_num == 0){//已发货
                        $orderdata['ship_status'] = '1';
                        $orderObj->save($orderdata);//更新订单发货状态
                    }else {//部分发货
                        $orderdata['ship_status'] = '2';
                        $orderObj->save($orderdata);//更新订单发货状态
                    }
                }
                //扣减库存
                $productObj         = &$this->app->model('products');
                $branch_productObj  = &$this->app->model('branch_product');
                $dly_corpObj        = &$this->app->model('dly_corp');
                $stock = array();
                //循环大发货单的items数据
                foreach ($dly['delivery_items'] as $dly_item){
                    $product = $productObj->dump(array('bn'=>$dly_item['bn']));
                    $product_id = $dly_item['product_id'];//货品ID
                    $branch_id = $dly['branch_id'];//仓库ID
                    $num = $dly_item['number'];//需要扣减的数量
                    //增加branch_product库存的数量改变
                    $branch_productObj->unfreez($branch_id,$product_id,$num);
                    $productObj->chg_product_store_freeze($product_id,$num,"-");
                    //记录商品发货数量日志
                    $this->createStockChangeLog($branch_id,$num,$product_id);
                }
                /*$corp  = $dly_corpObj->dump($dly['logi_id']);//物流公司信息
                //物流费用计算
                $area = $dly['consignee']['area'];
                $arrArea = explode(':', $area);
                $area_id = $arrArea[2];
                if (isset($corp['area_fee_conf']) && $corp['area_fee_conf']){
                    $area_fee_conf = unserialize($corp['area_fee_conf']);
                    foreach($area_fee_conf as $k=>$v){
                         $areas = explode(',',$v['areaGroupId']);

                         // 再次解析字符
                          foreach ($areas as &$strArea){
                            if (strpos($strArea, '|') !== false){
                               $strArea = substr($strArea, 0, strpos($strArea, '|'));
                                // 取当前area id对应的最上级的区域id
                                $objRegions = app::get('ectools')->model('regions');
                                $arrRegion = $objRegions->dump($area_id);
                                while ($row = $objRegions->getRegionByParentId($arrRegion['p_region_id'])){
                                     $arrRegion = $row;
                                     $tmp_area_id = $row['region_id'];
                                     if ($tmp_area_id == $strArea){
                                        $area_id = $tmp_area_id;
                                                break;
                                            }
                                        }
                                    }
                                }

                                if(in_array($area_id,$areas))
                                {
                                    //如果地区在其中，优先使用地区设置的配送费用，及公式
                                    $corp['firstprice'] = $v['firstprice'];
                                    $corp['continueprice'] = $v['continueprice'];
                                    $corp['dt_expressions'] = $v['dt_expressions'];
                                    break;
                                }
                            }
                 }


                $price = utils::cal_fee($corp['dt_expressions'], $weight, 0,$corp['firstprice'],$corp['continueprice']); //TODO 生成快递费用*/

                $datadly['delivery_id']          = $dly['delivery_id'];
                $datadly['process']              = 'true';
                $datadly['status']               = 'succ';
                $datadly['weight']               = $weight;
                $datadly['delivery_time'] = $delivery_time;
                //将最后的发货过程产生的物流费用 由 “ 预计物流费用”更改为“物流费用”
                $datadly['delivery_cost_actual'] = $delivery_cost_actual;

                $this->save($datadly);//更新发货单发货状态为已发货

                if (kernel::single('desktop_user')->get_id()) $opObj->write_log('delivery_process@ome', $dly['delivery_id'], '发货单发货完成');//log
            }else {
                /*
                 * 单个发货单处理
                 */
                $de = $dly['delivery_order'];
                $or = array_shift($de);
                $ord_id = $or['order_id'];
                if ($dly['type'] == 'normal'){//如果不为售后生成的发货单，才进行订单发货数量的更新
                    $this->consignOrderItem($dly);
                }
                /*$dly_corpObj = &$this->app->model('dly_corp');
                $corp  = $dly_corpObj->dump($dly['logi_id']);//物流公司信息
                //物流预算费用计算
                $area = $dly['consignee']['area'];
                $arrArea = explode(':', $area);
                $area_id = $arrArea[2];
                if (isset($corp['area_fee_conf']) && $corp['area_fee_conf']){
                    $area_fee_conf = unserialize($corp['area_fee_conf']);
                    foreach($area_fee_conf as $k=>$v){
                         $areas = explode(',',$v['areaGroupId']);
                         // 再次解析字符
                          foreach ($areas as &$strArea){
                            if (strpos($strArea, '|') !== false){
                               $strArea = substr($strArea, 0, strpos($strArea, '|'));
                                // 取当前area id对应的最上级的区域id
                                $objRegions = app::get('ectools')->model('regions');
                                $arrRegion = $objRegions->dump($area_id);
                                while ($row = $objRegions->getRegionByParentId($arrRegion['p_region_id'])){
                                     $arrRegion = $row;
                                     $tmp_area_id = $row['region_id'];
                                     if ($tmp_area_id == $strArea){
                                        $area_id = $tmp_area_id;
                                                break;
                                            }
                                        }
                                    }
                                }
                                if(in_array($area_id,$areas))
                                {
                                    //如果地区在其中，优先使用地区设置的配送费用，及公式
                                    $corp['firstprice'] = $v['firstprice'];
                                    $corp['continueprice'] = $v['continueprice'];
                                    $corp['dt_expressions'] = $v['dt_expressions'];
                                    break;
                                }
                            }
                 }

                $price = utils::cal_fee($corp['dt_expressions'], $weight, 0,$corp['firstprice'],$corp['continueprice']); //TODO 生成快递费用*/
                $dlydata['delivery_id']          = $dly['delivery_id'];
                $dlydata['process']              = 'true';
                $dlydata['status']               = 'succ';
                $dlydata['weight']               = $weight;
                $dlydata['delivery_time'] = $delivery_time;
                $dlydata['delivery_cost_actual'] = $delivery_cost_actual;

                $this->save($dlydata);//更新发货单发货状态为已发货

                $item_num = $this->countOrderSendNumber($ord_id);

                $orderdata['order_id'] = $ord_id;
                if ($item_num == 0){//已发货
                    $orderdata['ship_status'] = '1';
                    $orderObj->save($orderdata);//更新订单发货状态
                }else {//部分发货
                    $orderdata['ship_status'] = '2';
                    $orderObj->save($orderdata);//更新订单发货状态
                }

                //扣减库存
                $productObj         = &$this->app->model('products');
                $branch_productObj  = &$this->app->model('branch_product');

                //循环发货单的items数据
                $stock = array();
                foreach ($dly['delivery_items'] as $dly_item){
                    $product = $productObj->dump(array('bn'=>$dly_item['bn']));
                    $product_id = $dly_item['product_id'];//货品ID
                    $branch_id = $dly['branch_id'];//仓库ID
                    $num = $dly_item['number'];//需要扣减的数量
                    //增加branch_product库存的数量改变
                    $branch_productObj->unfreez($branch_id,$product_id,$num);
                    $productObj->chg_product_store_freeze($product_id,$num,"-");
                    //记录商品发货数量日志
                    $this->createStockChangeLog($branch_id,$num,$product_id);
                }

                if (kernel::single('desktop_user')->get_id()) $opObj->write_log('delivery_process@ome', $dly['delivery_id'], '发货单发货完成');//log
            }

            //删除批次号码段
            if ($service = kernel::servicelist('service.order'))
            foreach ($service as $object => $instance){
                if (method_exists($instance, 'destroy_running_no')){
                    $username = $dly['member_id'] ? $dly['member_id'] : 0;
                    $md5 = md5($dly['consignee']['addr'].$dly['consignee']['name'].$dly['consignee']['mobile']);
                    $instance->destroy_running_no($dly['shop_id'],$username,$md5);
                }
            }

            //调用发货相关api，比如订单的发货状态，库存的回写，发货单的回写
            $this->call_delivery_api($dly['delivery_id']);

            //如果有KPI考核插件，会增加发货人的考核
            if($oKpi = kernel::service('omekpi_deliverier_incremental')){
                if (kernel::single('desktop_user')->get_id()){
                    $opInfo = kernel::single('ome_func')->getDesktopUser();
                    $op_id = $opInfo['op_id'];
                    if(method_exists($oKpi,'deliveryIncremental')){
                        $oKpi->deliveryIncremental($op_id,$dly['delivery_id']);
                    }
                }
            }
            return true;

        }else{
            return false;
        }
    }
    
    function getDeliveryCost($dly_id,$weight=0){
    	$dly = $this->dump($dly_id,'*',array('delivery_items'=>array('*'),'delivery_order'=>array('*')));
    	$dly_corpObj = &$this->app->model('dly_corp');
        $corp  = $dly_corpObj->dump($dly['logi_id']);//物流公司信息
                //物流预算费用计算
                $area = $dly['consignee']['area'];
                $arrArea = explode(':', $area);
                $area_id = $arrArea[2];
                if (isset($corp['area_fee_conf']) && $corp['area_fee_conf']){
                    $area_fee_conf = unserialize($corp['area_fee_conf']);
                    foreach($area_fee_conf as $k=>$v){
                         $areas = explode(',',$v['areaGroupId']);
                         // 再次解析字符
                          foreach ($areas as &$strArea){
                            if (strpos($strArea, '|') !== false){
                               $strArea = substr($strArea, 0, strpos($strArea, '|'));
                                // 取当前area id对应的最上级的区域id
                                $objRegions = app::get('ectools')->model('regions');
                                $arrRegion = $objRegions->dump($area_id);
                                while ($row = $objRegions->getRegionByParentId($arrRegion['p_region_id'])){
                                     $arrRegion = $row;
                                     $tmp_area_id = $row['region_id'];
                                     if ($tmp_area_id == $strArea){
                                        $area_id = $tmp_area_id;
                                                break;
                                            }
                                        }
                                    }
                                }
                                if(in_array($area_id,$areas))
                                {
                                    //如果地区在其中，优先使用地区设置的配送费用，及公式
                                    $corp['firstprice'] = $v['firstprice'];
                                    $corp['continueprice'] = $v['continueprice'];
                                    $corp['dt_expressions'] = $v['dt_expressions'];
                                    break;
                                }
                            }
                 }

                $price = utils::cal_fee($corp['dt_expressions'], $weight, 0,$corp['firstprice'],$corp['continueprice']); //TODO 生成快递费用
    	return $price;
    }

    function searchOptions(){
        $parentOptions = parent::searchOptions();
        $childOptions = array('order_bn'=>app::get('base')->_('订单号'),
            'delivery_bn'=>app::get('base')->_('发货单号'),
            'ship_name'=>app::get('base')->_('收货人'),
            'member_uname'=>app::get('base')->_('用户名'),
            
            'product_bn'=>app::get('base')->_('货号'),
            'product_barcode'=>app::get('base')->_('条形码'),
			'delivery_ident'=>app::get('base')->_('打印批次号'),
        );
        return array_merge($childOptions,$parentOptions);
    }


    function getDeliveryOrderCreateTime($dly_ids){
        $str_dly_ids = implode(',', $dly_ids);
        $sql = 'SELECT order_createtime FROM sdb_ome_delivery  WHERE delivery_id IN('.$str_dly_ids.')';
        $rows = $this->db->select($sql);

        if($rows){
            $lenOrder = count($rows);
            $order_createtime = $rows[0]['order_createtime'];
            for($i=1;$i<$lenOrder;$i++){
                if(isset($rows[$i])){
                    if($order_createtime > $row[$i]['order_createtime']){
                        $order_createtime = $row[$i]['order_createtime'];
                    }
                }
            }
            return $order_createtime;
        }else{
            return false;
        }
    }

    function getAllTotalAmountByDelivery($delivery_order){
        $order_total_amount = 0;
        if(count($delivery_order)>1){//合并
            $is_vaild = true;
            foreach($delivery_order as $deli_order){
                $total_amount = $this->getTotalAmountByDelivery($deli_order['order_id'],$deli_order['delivery_id']);
                if($total_amount){
                    $order_total_amount += $total_amount;
                }else{
                     $is_vaild = false;
                     break;
                }
            }

            if(!$is_vaild){
                $order_total_amount = 0;
            }
        }else{//单张
            $delivery_order = current($delivery_order);
            $order_total_amount = $this->getTotalAmountByDelivery($delivery_order['order_id'],$delivery_order['delivery_id']);
        }

        return $order_total_amount;

    }

    function getTotalAmountByDelivery($order_id,$delivery_id){
        $order_total_amount = 0;
        $objOrders = &$this->app->model('orders');
        $order = $objOrders->order_detail($order_id);

        if($order['process_status'] == 'splited'){//已拆分
            $ids = $this->getDeliverIdByOrderId($order_id);
            if(count($ids) == 1){//发货单必须是一张
                 $order_total_amount = $order['total_amount'];
            }
        }

        return $order_total_amount;
    }

    /**
     * 根据订单ID获取发货单的商品
     *
     * @param $order_id
     * @return array
     */
    function getDeliverItemByOrderId($order_id){
        $list = $this->db->select("SELECT dt.* FROM sdb_ome_delivery_order AS dord
                                            LEFT JOIN sdb_ome_delivery AS d ON(dord.delivery_id=d.delivery_id)
                                            LEFT JOIN sdb_ome_delivery_items AS dt ON d.delivery_id = dt.delivery_id
                                            WHERE dord.order_id={$order_id} AND d.is_bind='false' AND d.disabled='false' AND d.status IN ('ready','progress','succ') AND d.pause='false'");
        $new_list = array();
        foreach($list as $item){
            if(!isset($new_list[$item['delivery_id']]))$new_list[$item['delivery_id']] = array();
            $new_list[$item['delivery_id']][] = $item;
        }

        return $new_list;
    }

    /**
     * 根据订单ID获取发货单列表
     *
     * @param $order_id
     * @return array
     */
    function getDeliversByOrderId($order_id){
        return $this->db->select("SELECT d.* FROM sdb_ome_delivery_order AS dord
                                            LEFT JOIN sdb_ome_delivery AS d ON(dord.delivery_id=d.delivery_id)
                                            WHERE dord.order_id={$order_id} AND d.is_bind='false' AND d.disabled='false' AND d.status IN ('ready','progress','succ') AND d.pause='false'");
    }

    /**
     * 统计已打印完成待校验的发货单总数
     */
    function countNoVerifyDelivery(){
    	$status_cfg = $this->app->getConf('ome.delivery.status.cfg');
    	if($status_cfg !=''){
    		if($status_cfg['set']['stock'] ==1 && $status_cfg['set']['delie'] == 1 ){
    			$filter = array(
		            'parent_id' => 0,
		            'stock_status' => 'true',
		            'deliv_status' => 'true',
		            'expre_status' => 'true',
		            'verify' => 'false',
		            'disabled' => 'false',
		            'pause' => 'false',
		            'status' => 'progress'
	             );
    		}
    		if($status_cfg['set']['stock'] ==1 && $status_cfg['set']['delie'] ==0){
    			$filter = array(
	                'parent_id' => 0,
	                'stock_status' => 'true',
	                'expre_status' => 'true',
	                'verify' => 'false',
	                'disabled' => 'false',
	                'pause' => 'false',
	                'status' => 'progress'
                 );
    		}
    	   if($status_cfg['set']['stock'] ==0 && $status_cfg['set']['delie'] ==1){
                $filter = array(
                    'parent_id' => 0,
                    'deliv_status' => 'true',
                    'expre_status' => 'true',
                    'verify' => 'false',
                    'disabled' => 'false',
                    'pause' => 'false',
                    'status' => 'progress'
                 );
            }
    	   if($status_cfg['set']['stock'] ==0 && $status_cfg['set']['delie'] ==0 ){
                $filter = array(
                    'parent_id' => 0,
                    'expre_status' => 'true',
                    'verify' => 'false',
                    'disabled' => 'false',
                    'pause' => 'false',
                    'status' => 'progress'
                 );
            }
    	}else{
    		$filter = array(
            'parent_id' => 0,
            'stock_status' => 'true',
            'deliv_status' => 'true',
            'expre_status' => 'true',
            'verify' => 'false',
            'disabled' => 'false',
            'pause' => 'false',
            'status' => 'progress',
    		'addonSQL' => ' logi_no IS NOT NULL ',
             );
    	}
        $num = $this->count_logi_no($filter);
        return $num;
    }

    /**
     * 统计已校验待发货的发货单总数
     */
    function countNoProcessDelivery(){
        $filter = array(
            'parent_id' => 0,
//            'stock_status' => 'true',
//            'deliv_status' => 'true',
//            'expre_status' => 'true',
            'verify' => 'true',
            'disabled' => 'false',
            'pause' => 'false',
            'process' => 'false',
            'status' => 'progress'
        );
        $num = $this->count($filter);
        return $num;
    }

    function getOrderByDeliveryId($delivery_id){
        if ($delivery_id){
            $sql = "SELECT O.pay_status,O.order_bn FROM `sdb_ome_orders` as O LEFT JOIN
                `sdb_ome_delivery_order` as DO ON DO.order_id=O.order_id
                WHERE DO.delivery_id ='".$delivery_id."'";

            $rows = $this->db->selectrow($sql);
            return $rows;
        }
    }

    //从载方法 以解决 发货中未录入快递单号不能过滤的bug
    function getlist_logi_no($cols='*', $filter=array(), $offset=0, $limit=-1, $orderType=null){
        if(!$cols){
            $cols = $this->defaultCols;
        }
        if(!empty($this->appendCols)){
            $cols.=','.$this->appendCols;
        }
        if($this->use_meta){
             $meta_info = $this->prepare_select($cols);
        }
        $orderType = $orderType?$orderType:$this->defaultOrder;
        if($filter['logi_no'] == 'NULL'){
            unset($filter['logi_no']);
            $sql = 'SELECT '.$cols.' FROM `'.$this->table_name(true).'` WHERE '.$this->_filter($filter).' AND `logi_no` IS NULL';
        }else{
            $sql = 'SELECT '.$cols.' FROM `'.$this->table_name(true).'` WHERE '.$this->_filter($filter);
        }
        if($orderType)$sql.=' ORDER BY '.(is_array($orderType)?implode($orderType,' '):$orderType);
        $data = $this->db->selectLimit($sql,$limit,$offset);
        $this->tidy_data($data, $cols);
        if($this->use_meta && count($meta_info['metacols']) && $data){
            foreach($meta_info['metacols'] as $col){
                $obj_meta = new dbeav_meta($this->table_name(true),$col,$meta_info['has_pk']);
                $obj_meta->select($data);
            }
        }
        return $data;
    }

    public function count_logi_no($filter=null){
        if($filter['logi_no'] == 'NULL'){
            unset($filter['logi_no']);
            $row = $this->db->select('SELECT count(*) as _count FROM `'.$this->table_name(1).'` WHERE '.$this->_filter($filter).' AND `logi_no` IS NULL');
        }else{
            $row = $this->db->select('SELECT count(*) as _count FROM `'.$this->table_name(1).'` WHERE '.$this->_filter($filter));
        }
        return intval($row[0]['_count']);
    }

    public function getPrintStockPrice($ids){
        $tmp = array();
        foreach($ids as $delivery_id){
            $delivery = $this->db->selectRow('SELECT is_bind FROM sdb_ome_delivery WHERE delivery_id='.$delivery_id);
            if($delivery['is_bind'] == 'true'){
                $sub_delivery_to_order = $this->db->select('SELECT d.delivery_id,do.order_id FROM sdb_ome_delivery as d
                    LEFT JOIN  sdb_ome_delivery_order do ON d.delivery_id = do.delivery_id WHERE d.parent_id='.$delivery_id);
                $delivery_ids = array();
                foreach($sub_delivery_to_order as $val){
                    $delivery_ids[] = $val['delivery_id'];
                }
               $this->_getPrintStockPrice($delivery_ids,$tmp);
            }else{
               $delivery_id = array($delivery_id);
               $this->_getPrintStockPrice($delivery_id,$tmp);
            }
        }

        return $tmp;
    }

    function _getPrintStockPrice($delivery_id,&$tmp){

     /*$order_item_list = $this->db->select('SELECT distinct di.bn, oi.price,oi.item_type,do.delivery_id,di.number FROM sdb_ome_delivery_items as di
                    LEFT JOIN sdb_ome_delivery_order as do  ON do.delivery_id = di.delivery_id
                    LEFT JOIN sdb_ome_order_items as oi ON oi.order_id = do.order_id
                    WHERE do.delivery_id='.$delivery_id);*/
                $delivery_item_list = $this->db->select('SELECT di.bn,di.delivery_id,di.number,d2o.order_id FROM sdb_ome_delivery_items as di
                    LEFT JOIN sdb_ome_delivery_order as d2o ON d2o.delivery_id = di.delivery_id
                    WHERE d2o.delivery_id IN('.implode(',',$delivery_id).')');
                $order_item_list = $this->db->select('SELECT oi.order_id,oi.bn,oi.price,oi.item_type,oi.nums FROM sdb_ome_order_items as oi
                    LEFT JOIN sdb_ome_delivery_order as d2o ON d2o.order_id = oi.order_id
                    WHERE d2o.delivery_id IN('.implode(',',$delivery_id).')');

                $tmp_order_item_list = array();
                $pkg_item_list = array();
                foreach($order_item_list as $order_item){
                    if($order_item['item_type'] == 'product'){
                        $tmp_order_item_list[$order_item['order_id']][$order_item['bn']] = $order_item;
                    }else{
                        if(!isset($pkg_item_list[$order_item['order_id']][$order_item['bn']]))$pkg_item_list[$order_item['order_id']][$order_item['bn']]=0;
                        $pkg_item_list[$order_item['order_id']][$order_item['bn']] += $order_item['nums'];
                    }
                }

                foreach($delivery_item_list as $delivery_item){
                    if(!isset($tmp_order_item_list[$delivery_item['order_id']][$delivery_item['bn']])){
                        continue;
                    }

                    if(isset($pkg_item_list[$delivery_item['order_id']][$delivery_item['bn']])){
                        $delivery_item['number'] -= $pkg_item_list[$delivery_item['order_id']][$delivery_item['bn']];
                        unset($pkg_item_list[$delivery_item['order_id']][$delivery_item['bn']]);
                    }

                    $delivery_item = array_merge($delivery_item,$tmp_order_item_list[$delivery_item['order_id']][$delivery_item['bn']]);
                    if(!isset($tmp[$delivery_item['bn']]))$tmp[$delivery_item['bn']]=0;
                    $tmp[$delivery_item['bn']] += $delivery_item['price'] * $delivery_item['number'];
                }
    }

    /**
     * 根据物流ID获取站内对应的物流公司
     * @param array $logi_ids
     *
     */
    function getOMELogiName($logi_ids){
		if(!$logi_ids)return false;
        $logi_names = $this->db->select('SELECT corp_id,name FROM sdb_ome_dly_corp WHERE corp_id IN('.implode(',',$logi_ids).')');
        $new_logi_names = array();
        if($logi_names){
            foreach($logi_names as $l){
                $new_logi_names[$l['corp_id']] = $l['name'];
            }
            return $new_logi_names;
        }else{
            return false;
        }
    }

	public function getPrintProductName($ids){
        $printProductNames = array();
        $sql = 'SELECT distinct oi.order_id,oi.name,oi.bn,oi.addon,bp.store_position
                    FROM sdb_ome_delivery_order AS d2o
                LEFT JOIN sdb_ome_order_items AS oi
                    ON d2o.order_id = oi.order_id
                LEFT JOIN (
                    SELECT bpp.*
                        FROM (
                            SELECT pos_id,product_id
                            FROM sdb_ome_branch_product_pos
                            ORDER BY create_time DESC
                        )bpp
                    GROUP BY bpp.product_id
                 )bb
                    ON bb.product_id = oi.product_id
                 LEFT JOIN sdb_ome_branch_pos bp
                    ON bp.pos_id = bb.pos_id
                WHERE d2o.delivery_id IN('.implode(',',$ids).') ORDER BY d2o.order_id';
        $rows = $this->db->select($sql);
        foreach($rows as $row){
            $row['bn'] = trim($row['bn']);

            if(isset($printProductNames[$row['bn']]))continue;
			$row['addon'] = ome_order_func::format_order_items_addon($row['addon']);

            $printProductNames[$row['bn']] = $row;
        }

        return $printProductNames;
    }
    
    function getOrderIdsByDeliveryIds($delivery_ids){
    	$rows = $this->db->select('select order_id from sdb_ome_delivery_order where delivery_id in('.implode(',', $delivery_ids).')');
    	$order_ids = array();
    	foreach($rows as $row){
    		$order_ids[] = $row['order_id'];
    	}
    	
    	return $order_ids;
    }
}
?>